﻿/*****************************************************************//**
 * @file    FITKAbsGeoDatum.h
 * @brief   体特征处理数据抽象类。

 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-08-30
 *********************************************************************/

#ifndef  FITKABSGEODATUM_H
#define  FITKABSGEODATUM_H

#include "FITK_Kernel/FITKCore/FITKAbstractNDataObject.h"
#include "FITK_Kernel/FITKCore/FITKAbstractDataObject.h"
#include "FITK_Kernel/FITKCore/FITKAbstractDataManager.hpp"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKSignalTransfer.h"

#include "FITKGeoEnum.h"
#include "FITKInterfaceGeometryAPI.h"

namespace Interface
{
    /**
     * @brief  源对象.
     * @author YanZhiHui (chanyuantiandao@126.com)
     * @date   2024-08-22
     */
    class SourceObject {
    public:
        /**
         * @brief  是否为基准.
         * @return 基准：true；普通模型面：false
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        bool isDatumObj() const { return m_IsDatum; }
        /**
         * @brief  获取基准ID.
         * @return 基准ID或者0
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        int datumId() const {
            return m_IsDatum ? m_DatumId : 0;
        }
        /**
         * @brief  设置基准.
         * @param  id 基准id
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        void setDatum(int id) {
            m_IsDatum = true;
            m_DatumId = id;
        }
        /**
         * @brief  获取cmdID.
         * @return 命令ID或者0
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        int cmdId() const {
            return m_IsDatum ? 0 : m_CmdId;
        }
        /**
         * @brief  获取虚拓扑ID.
         * @return 虚拓扑ID或者0
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        int virtualTopoId() const {
            return m_IsDatum ? 0 : m_VirtualTopoId;
        }
        /**
         * @brief  设置虚拓扑.
         * @param  cmdId 命令id
         * @param  virtualTopoId 虚拓扑id
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        void setVirtualTopo(int cmdId, int virtualTopoId) {
            m_IsDatum = false;
            m_CmdId = cmdId;
            m_VirtualTopoId = virtualTopoId;
        }
        /**
         * @brief  是否为空形状.
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-08-22
         */
        bool isNull() const {
            return m_IsDatum ? m_DatumId <= 0 : (m_CmdId <= 0 || m_VirtualTopoId <= 0);
        }
        /**
          * @brief  重置形状，置空(isNull() == true).
          * @author YanZhiHui (chanyuantiandao@126.com)
          * @date   2024-08-22
          */
        void reset() { m_CmdId = 0; m_VirtualTopoId = 0; m_DatumId = 0; }
    private:
        /**
         * @brief  命令CommandID.
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-08-22
         */
        int m_CmdId{ 0 };
        /**
         * @brief  虚拓扑ID.
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-08-22
         */
        int m_VirtualTopoId{ 0 };
        /**
         * @brief  源基准的ID.
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        int m_DatumId{ 0 };
        /**
         * @brief  是否为基准.
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-09-04
         */
        bool m_IsDatum{};
    };


    /**
     * @brief   基准元素抽象类。
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-08-30
     */
    class FITKInterfaceGeometryAPI FITKAbsGeoDatum : public Core::FITKAbstractNDataObject
    {
        FITKCLASS(Interface, FITKAbsGeoDatum);
    public:
        /**
         * @brief   基准元素创建方式枚举。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-31
         */
        enum DatumCreatedType
        {
            DCT_System = 0,
            DCT_UserDefine
        };

        /**
         * @brief   构造函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKAbsGeoDatum() = default;

        /**
         * @brief   析构函数。[虚函数]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        virtual ~FITKAbsGeoDatum() = default;

        /**
         * @brief   设置基准元素位置。
         * @param   pos：坐标
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        void setPosition(double* pos);

        /**
         * @brief   获取基准元素位置。
         * @param   pos：坐标
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        void getPosition(double* pos);

        /**
         * @brief   获取基准元素类型。[纯虚函数]
         * @return  基准元素类型
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        virtual FITKGeoEnum::FITKDatumType getDatumType() = 0;

        /**
         * @brief   获取基准元素可编辑性。
         * @return  是否可编辑
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-31
         */
        bool editable();

        /**
         * @brief   更新数据对象。[虚函数]
         * @return  是否更新成功
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-04
         */
        virtual bool update() { return true; };

        /**
         * @brief  打印信息到控制台.
         * @param  type 信息类型 1-normal 2-warning 3-error 4-info
         * @param  msg 信息内容
         * @author YanZhiHui (chanyuantiandao@126.com)
         * @date   2024-08-28
         */
        void printLog(QString msg, int type = 1)
        {
            AppFrame::FITKSignalTransfer* sigTrans = FITKAPP->getSignalTransfer();
            if (sigTrans)
            {
                sigTrans->outputMessageSig(type, msg);
            }
        }

    protected:
        /**
         * @brief   位置坐标。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        double m_pos[3]{ 0., 0., 0. };

        /**
         * @brief   基准元素创建方式。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-31
         */
        DatumCreatedType m_createdType = DCT_UserDefine;

        // 指定数据管理器为友元类。
        friend class FITKDatumList;

    };

    /**
     * @brief   基准点类。
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-08-30
     */
    class FITKInterfaceGeometryAPI FITKAbsGeoDatumPoint : public FITKAbsGeoDatum
    {
    public:
        /**
         * @brief   构造函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKAbsGeoDatumPoint() = default;

        /**
         * @brief   析构函数。[虚函数]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        virtual ~FITKAbsGeoDatumPoint() = default;

        /**
         * @brief   获取基准元素类型。[重写]
         * @return  基准元素类型
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKGeoEnum::FITKDatumType getDatumType() override;

    };

    /**
     * @brief   基准线类。
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-08-30
     */
    class FITKInterfaceGeometryAPI FITKAbsGeoDatumLine : public FITKAbsGeoDatum
    {
    public:
        /**
         * @brief   构造函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKAbsGeoDatumLine() = default;

        /**
         * @brief   析构函数。[虚函数]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        virtual ~FITKAbsGeoDatumLine() = default;

        /**
         * @brief   获取基准元素类型。[虚函数][重写]
         * @return  基准元素类型
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKGeoEnum::FITKDatumType getDatumType() override;

        /**
         * @brief   设置基准线信息。
         * @param   pos1：位置1
         * @param   pos2：位置2
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-05
         */
        void setPositions(double* pos1, double* pos2);

        /**
         * @brief   获取基准线信息。
         * @param   pos1：位置1
         * @param   pos2：位置2
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-05
         */
        void getPositions(double* pos1, double* pos2);

        /**
         * @brief   设置基准线结束坐标。
         * @param   pos：坐标
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-04
         */
        void setPosition2(double* pos);

        /**
         * @brief   获取基准线结束坐标。
         * @param   pos：坐标
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-04
         */
        void getPosition2(double* pos);

    protected:
        /**
         * @brief   基准线结束坐标。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        double m_pos2[3]{ 0., 0., 1. };

    };

    /**
     * @brief   基准平面类。(默认XOY平面)
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-08-30
     */
    class FITKInterfaceGeometryAPI FITKAbsGeoDatumPlane : public FITKAbsGeoDatum
    {
    public:
        /**
         * @brief   构造函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKAbsGeoDatumPlane() = default;

        /**
         * @brief   析构函数。[虚函数]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        virtual ~FITKAbsGeoDatumPlane() = default;

        /**
         * @brief   获取基准元素类型。[重写]
         * @return  基准元素类型
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        FITKGeoEnum::FITKDatumType getDatumType() override;

        /**
         * @brief   设置基准面信息。
         * @param   pos：面中心点坐标
         * @param   normal：面法向
         * @param   up：面向上方向
         * @return  是否为有效平面
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-05
         */
        void setPlane(double* pos, double* normal, double* up);

        /**
         * @brief   获取基准面信息。
         * @param   pos：面中心点坐标
         * @param   normal：面法向
         * @param   up：面向上方向
         * @return  是否为有效平面
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-09-05
         */
        void getPlane(double* pos, double* normal, double* up);

        /**
         * @brief   设置基准面法向。
         * @param   nor：法向
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        void setNormal(double* nor);

        /**
         * @brief   获取基准面法向。
         * @param   nor：法向
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        void getNormal(double* nor);

        /**
         * @brief   设置基准面向上方向。
         * @param   up：向上方向
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        void setUp(double* up);

        /**
         * @brief   获取基准面向上方向。
         * @param   up：向上方向
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        void getUp(double* up);

    protected:
        /**
         * @brief   基准面法向。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        double m_nor[3]{ 0., 0., 1. };

        /**
         * @brief   基准面向上方向。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        double m_up[3]{ 0., 1., 0. };
    };

    /**
     * @brief   基准元素管理器类。
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-08-30
     */
    class FITKInterfaceGeometryAPI FITKDatumList :
        public Core::FITKAbstractDataManager<Interface::FITKAbsGeoDatum>
    {
    public:
        /**
         * @brief   构造函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        explicit FITKDatumList();

        /**
         * @brief   析构函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-08-30
         */
        virtual ~FITKDatumList() = default;

    };
}

#endif // !FITKABSGEODATUM_H
